
import { mergeOptions, getContainer } from "./utils";
import { initState } from "./state";
import { compileToFunction } from "./compile/index.js";
import { mountComponent } from "./lifecycle";
import Watcher from "./observer/watcher";

export function callHook ( vm, lifecycle ) {
  const lifecycles = vm.$options[ lifecycle ]
  if ( lifecycles ) {
    lifecycles.forEach( lifecycle => {
      lifecycle.call( vm )
    } );
  }
}

export function initMixin ( Vue ) {
  // initoptionsAPI初始化
  Vue.prototype._init = function ( options ) {
    const vm = this
    // 合并mixin的options
    vm.$options = mergeOptions( Vue.options, options );
    // 触发生命周期钩子
    callHook( vm, "beforeCreate" );
    // 状态进行初始化:props  data  computed watch
    initState( vm );
    callHook( vm, 'created' )
    // 如果有el属性，会调用$mount进行挂载
    if ( options.el ) {
      vm.$mount( options.el );
    }
  }


  Vue.prototype.$mount = function ( el ) {
    const vm = this;
    vm.$el = getContainer( el )
    const options = vm.$options;
    // render -> template -> outerHTML
    // 如果没有render函数，会调用compileToFunction进行ast解析，将模转换成render函数
    if ( !options.render ) {
      let template = options.template;
      if ( !template ) {
        if ( vm.$el ) {
          template = vm.$el.outerHTML;
        }
      }
      if ( template ) {
        options.render = compileToFunction( template );
      }
    }
    // 组件渲染流程
    mountComponent( vm, el );
  }


  Vue.prototype.$watch = function ( key, handler ) {
    new Watcher( this, key, handler, { user: true } );
  }

}